// 云对象教程: https://uniapp.dcloud.net.cn/uniCloud/cloud-obj
// jsdoc语法提示教程：https://ask.dcloud.net.cn/docs/#//ask.dcloud.net.cn/article/129
module.exports = {
	_before: function() { // 通用预处理器

	},
	/**
	 * getMenu获取menu树形结构数据
	 * @param role {array} 当前管理员角色
	 * @returns {object} 返回menu表树形结构数据
	 */
	async getMenuTreeStructure(roles) {
		// 参数校验，如无参数则不需要
		if (!roles) return { errCode: 'PARAM_IS_NULL', errMsg: '参数不能为空' };
		const db = uniCloud.database();
		const dbCmd = db.command;
		const dbJql = uniCloud.databaseForJQL();
		const collectionName = "menu";
		const field = "_id,title,icon,menu_id,is_show,parent_id,sort,url,is_alibaba_icon,create_date,role,create_uid";
		try {
			let isSuper = false;
			let roleData = await dbJql.collection("roles").where({_id:dbCmd.in(roles) }).field("permission").get();
			roleData = roleData.data;
			roles = roleData.map(item => { return item.permission }).flat();// 合并数组
			const role = [...new Set(roles)]; // 数组去重
			let where = { is_show:1, _id:dbCmd.in(role)  } ; // 默认查询条件
			const fullData = await dbJql.collection(collectionName).where({parent_id: null,...where}).limit(999).field(field).orderBy("sort asc").get();
			async function fetchSubClasses(item, collectionName, field) {
				const subClass = await dbJql.collection(collectionName).where({parent_id: item._id,...where}).limit(999).field(field).orderBy("sort asc").get();
				const subClassData = subClass.data.map(async subItem => {
					// 为每个子项（如果有）获取子项
					const children = subClass.data.length > 0 ? await fetchSubClasses(subItem, collectionName, field) : [];
					return {...subItem, children };
				});
				// 使用Promise.all等待所有Promise解决
				return Promise.all(subClassData);
			}
			// 假设fullData已经定义，并且它是一个具有数据属性的对象，该属性包含一个项目数组。
			const result = await Promise.all(fullData.data.map(async item => {
				const children = await fetchSubClasses(item, collectionName, field);
				return {  ...item,  children   };
			}));
			// 返回结果
			return {
				code: 200, message: "获取成功", result:result
			}
		} catch (error) {
			// 返回错误结果
			return { message: '内部错误', error }
		}

	},
	/**
	 * getMenu获取menu列表结构数据
	 * @returns {object} 返回menu表列表结构数据
	 */
	async getMenuListStructure() {
		// 参数校验，如无参数则不需要
		if (false) return { errCode: 'PARAM_IS_NULL', errMsg: '参数不能为空' };
		const dbJql = uniCloud.databaseForJQL();
		const collectionName = "menu";
		const field = "_id,title,icon,menu_id,is_show,parent_id,sort,url,is_alibaba_icon,create_date,create_uid,role";
		try {
			const fullData = await dbJql.collection(collectionName).where({parent_id: null}).limit(999).field(field).orderBy("sort asc").get();
			async function fetchSubClasses(item, collectionName, field) {
				const subClass = await dbJql.collection(collectionName).where({parent_id: item._id}).limit(999).field(field).orderBy("sort asc").get();
				const subClassData = subClass.data.map(async subItem => {
					// 为每个子项（如果有）获取子项
					let children = subClass.data.length > 0 ? await fetchSubClasses(subItem, collectionName, field) : [];
					temp = [...children]
					return [ { ...subItem, },...temp ]
				});
				// 使用Promise.all等待所有Promise解决
				return Promise.all(subClassData);
			}
			// 假设fullData已经定义，并且它是一个具有数据属性的对象，该属性包含一个项目数组。
			let result = await Promise.all(fullData.data.map(async item => {
				let children = await fetchSubClasses(item, collectionName, field);
				children = [...children] ;
				return  [ item,...children ];
			}));
			function flattenArray(arr) {
				let result = [];
				arr.forEach(item => {
					if (Array.isArray(item)) {
						result = result.concat(flattenArray(item));
					} else {
						result.push(item);
					}
				});
			  return result;
			}
			result = flattenArray(result);
			return { code: 200, message: "获取成功", result };
		} catch (error) {
			// 返回错误结果
			return { message: '内部错误', error }
		}
	
	},
	/**
	 * addMenu添加menu数据
	 * @param data 要添加的数据
	 * @returns {object} 返回添加成功数据
	 */
	async addMenu(data){
		// 参数校验，如无参数则不需要
		if (!data) return {errCode: 'PARAM_IS_NULL',errMsg: '参数不能为空'} ;
		const db = uniCloud.database() ;
		const collectionName = "menu" ;
		try{
			data.sort = parseInt(data.sort);
			const result = await db.collection(collectionName).add(data) ;
			// 返回结果
			return {
				code:200, message:"添加成功", result:result }
		}catch(error){
			// 返回结果
			return { message:'内部错误',error  }
		}
	},
	/**
	 * 验证menuID的唯一性
	 * @param menuId menuId
	 * @returns {object} 返回menuId是否唯一
	 */
	async verifyUniquenessMenuId(menuId) {
		// 参数校验，如无参数则不需要
		if (!menuId) return {errCode: 'PARAM_IS_NULL',errMsg: '缺少参数'} ;
		const db = uniCloud.databaseForJQL() ;
		const collectionName = "menu" ;
		try{
			const data = await db.collection(collectionName).where({menu_id:menuId}).get({getOne:true}) ;
			// 返回结果
			return { code:200, message:"校验完成",result:data.affectedDocs }
		}catch(error){
			// 返回结果
			return {message:'内部错误',error }
		}
	},
	/**
	 * getMenuOne获取menu修改默认数据
	 * @param uid 数据的_id
	 * @returns {object} 返回menu表内容
	 */
	async getMenuOne(uid) {
		// 参数校验，如无参数则不需要
		if (!uid) return {errCode: 'PARAM_IS_NULL',errMsg: '缺少参数'} ;
		const db = uniCloud.databaseForJQL() ;
		const collectionName = "menu" ;
		try{
			const data = await db.collection(collectionName).doc(uid).get({getOne:true}) ;
			let parent = null ;
			if(data.data.parent_id) parent = await db.collection(collectionName).doc(data.data.parent_id).get({getOne:true}) ;
			// 返回结果
			return {
				code:200,
				message:"获取成功",
				result:data.data,
				parent:parent ? parent.data:null
			}
		}catch(error){
			// 返回结果
			return {message:'内部错误',error }
		}
	},
	/** 获取子类数据
	 *  @param childrenId 父类id
	 * @return {result} 返回父类数据 */
	async getMenuChildId(parentId) {
		// 参数校验，如无参数则不需要
		if (!parentId) return {errCode: 'PARAM_IS_NULL',errMsg: '缺少参数'} ;
		const db = uniCloud.databaseForJQL() ;
		const collectionName = "menu" ;
		try{
			const parent = await db.collection(collectionName).where({parent_id:parentId }).get({getOne:true}) ;
			return parent ? parent:null
			
		}catch(error){
			return { message:'内部错误',error }
		}
	},
	/** 获取可作为父类的数据
	 *  @param childrenId 父类id
	 * @return {result} 返回父类数据 */
	async getParentData() {
		// 参数校验，如无参数则不需要
		if (!true) return {errCode: 'PARAM_IS_NULL',errMsg: '缺少参数'} ;
		const db = uniCloud.databaseForJQL() ;
		const collectionName = "menu" ;
		try{
			const data = await db.collection(collectionName).where({url: null}).get({getOne:false}) ;
			return {
				code:200,
				message:'获取成功',
				result:data
			}
			
		}catch(error){
			return { message:'内部错误',error }
		}
	},
	/**
	 * updateMenu修改数据
	 * @param data 要修改的数据
	 * @param where  修改条件
	 * @returns {object} 返回menu修改成功数据
	 */
	async updateMenu(data,where) {
		// 参数校验，如无参数则不需要
		if (!data,!where) return {errCode: 'PARAM_IS_NULL',errMsg: '参数不能为空'} ;
		const db = uniCloud.database() ;
		const collectionName = "menu" ;
		try{
			data.sort = parseInt(data.sort);
			delete data._id ; // 删除_id
			const result = await db.collection(collectionName).where(where).update(data) ;
			// 返回结果
			return {
				code:200,
				message:"修改成功",
				result:result
			}
		}catch(error){
			// 返回结果
			return {message:'内部错误',error }
		}
	},
	/**
	 * 删除menu数据
	 * @param uid String 数据的 _id 
	 * @returns {object} 返回menu删除成功
	 */
	async deleteMenu(uid) {
		// 参数校验，如无参数则不需要
		if (!uid) return {errCode: 'PARAM_IS_NULL',errMsg: '缺少参数'} ;
		const db = uniCloud.databaseForJQL() ;
		const collectionName = "menu" ;
		try{
			let parent = await uniCloud.importObject(collectionName).getMenuChildId(uid) ;
			if(parent.affectedDocs == 0 ){
				const data = await db.collection(collectionName).doc(uid).remove() ;
				// 返回结果
				return { code:200,message:"删除成功",result:data }
			}
			
			return {
				code:404,message:"当前分类下面有子分类",
				error:"删除失败"
			}
		
		}catch(error){
			// 返回结果
			return {message:'内部错误',error }
		}
	},
}